#include "PicManager.h"
#include <fcntl.h>
#include <muduo/base/Logging.h>
#include <iostream>

#define ByteArray std::vector<uint8_t>
using namespace std;

PicManager::PicManager()
{

}

void PicManager::setPicReadyCallback(const PicReadyFunctor &cb)
{
    picReadyCb_ = cb;
}

void PicManager::saveImage(const std::vector<uint8_t> &data)
{
//    std::stringstream ss;
//    ss << "start ptr:" << std::hex << std::setw(2) << std::setfill('0')
//       << (int)(data.at(0) & 0xFF) << (int)(data.at(1) & 0xFF);
//    qDebug() << ss.str().c_str();
    FILE * fp = fopen("pic.jpg", "wb");
    printf("fp:%X\n", fp);
    if (fp)
    {
        fwrite(data.data(), data.size(), 1, fp);
        printf("write fp well.\n");
        fclose(fp);
        picReadyCb_("./pic.jpg");
    }
}

void PicManager::onReceiveFrame(PicFramePtr frame)
{
    // 若没开始记录图片
    if(currentPicId_ == -1)
    {
        if(frame->category_ == FrameCategory::START)
        {   // 首帧
            currentPicId_ = frame->picId_;
            picMap_.insert(pair<int, PicFramePtr>(frame->packIdx_, frame));
            LOG_INFO << "record START frame[0]";
        }
        else
        {  // 还没开始记录图片, 收到不是首帧. 丢弃这些帧
        }
    }
    else    // 已经在记录图片过程中
    {
        // 若收到帧的图ID与当前记录的图ID不匹配,则删去之前的所有帧,并重新处理该帧.
        if(currentPicId_ != frame->picId_)
        {
            picMap_.clear();
            currentPicId_ = -1;
            onReceiveFrame(frame);
            return;
        }

        if(frame->category_ == FrameCategory::PROCESSING)
        {
            auto pv = picMap_.find(frame->packIdx_);
            if(pv != picMap_.end())
            {
                LOG_INFO << "recover PROCESSING frame[" << frame->packIdx_ << "]";
                pv->second = frame;
            }
            else
            {
                LOG_INFO << "record PROCESSING frame[" << frame->packIdx_ << "]";
                picMap_.insert(pair<int, PicFramePtr>(frame->packIdx_, frame));
            }
        }
        else if(frame->category_ == FrameCategory::END)
        {
            LOG_INFO << "record END frame[" << frame->packIdx_ << "]";
            picMap_.insert(pair<int, PicFramePtr>(frame->packIdx_, frame));
            // 检查: 包必须少于255个, 且包序号连续
            if(picMap_.size() <= 255 &&  picMap_.size() == frame->packIdx_ + 1)
            {
                ByteArray picData;
                for (int i = 0; i < picMap_.size(); i++)
                {
                    auto it = picMap_.find(i);
                    if(it != picMap_.end())
                    {
                        PicFramePtr frame = (*it).second;
                        auto itfb = frame->body_.begin();
                        while (itfb != frame->body_.end()) {
                            picData.push_back(static_cast<uint8_t>((*itfb)));
                            itfb++;
                        }
                    }
                }
                // 此处应给远端一个应答:(图片ID)#OK
                LOG_INFO << "receive a img. frame Num:" << picMap_.size()
                         << "pic size: " << picData.size()
                         << " bytes(" << picData.size() / 1024.0f << "KB)";
                saveImage(picData);
                // emit signal_receiveImage(picData);
            }
            // 清理构建图像的缓存
            picMap_.clear();
            currentPicId_ = -1;
        }
    }
}
